package org.hackystat.linkedservicedata.ui.issues;

import java.awt.Color;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.text.SimpleDateFormat;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import org.hackystat.linkedservicedata.sparql.IssueQuery;
import org.hackystat.linkedservicedata.ui.LinkedServiceDataUI;

/**
 * Issue search wizard panel.
 *
 * @author Myriam Leggieri.
 *
 */
public class IssueSearchWizard extends JFrame implements ItemListener, ActionListener {

  /**
   * Auto-generated serial version ID.
   */
  private static final long serialVersionUID = -2448725738480402598L;

  /** Parent frame. */
  LinkedServiceDataUI mainframe = null;

  /** Name label. */
  public JLabel idLabel = null;

  /** Assigned to label. */
  public JLabel assignedToLabel = null;

  /** Type label. */
  public JLabel typeLabel = null;

  /** Status label. */
  public JLabel statusLabel = null;

  /** Priority label. */
  public JLabel priorityLabel = null;

  /** Milestone label. */
  public JLabel milestoneLabel = null;

  /** Creation date label. */
  public JLabel creationDateLabel = null;

  /** Closure date label. */
  public JLabel closureDateLabel = null;

  /** Modification date label. */
  public JLabel modificationDateLabel = null;

  /** Creation date text. */
  public JFormattedTextField creationDateText = null;

  /** Closure date text. */
  public JFormattedTextField closureDateText = null;

  /** Last modification date text. */
  public JFormattedTextField modifiedDateText = null;

  /** Name text. */
  public JTextField idText = null;

  /** Surname text. */
  public JTextField assignedToText = null;

  /** Nickname text. */
  public JTextField typeText = null;

  /** Email text. */
  public JTextField statusText = null;

  /** Homepage text. */
  public JTextField priorityText = null;

  /** Weblog text. */
  public JTextField milestoneText = null;

  /** SeeAlso URI container. */
  public String[] seeAlso = null;

  /** SeeAlso URI JList. */
  public JList seeAlsoList = null;

  /** SeeAlso 'add' button. */
  public JButton seeAlsoButton = null;

  /** Search button. */
  public JButton searchButton = null;

  /** Cancel button. */
  public JButton cancelButton = null;

  /** SeeAlso label. */
  public JLabel seeAlsoLabel = null;

  /** SeeAlso text field. */
  public JTextField seeAlsoText = null;

  /** Duplicates label. */
  public JLabel duplicatesLabel = null;

  /** duplicates URI JList. */
  public JList duplicatesList = null;

  /** duplicates 'add' button. */
  public JButton duplicatesButton = null;

  /** duplicates text field. */
  public JTextField duplicatesText = null;

  /** duplicates list label. */
  private JLabel duplicatesListLabel = null;

  /** tags label. */
  public JLabel tagsLabel = null;

  /** tags URI JList. */
  public JList tagsList = null;

  /** tags 'add' button. */
  public JButton tagsButton = null;

  /** tags text field. */
  public JTextField tagsText = null;

  /** tags list label. */
  private JLabel tagsListLabel = null;

  /** SameAs label. */
  public JLabel sameAsLabel = null;

  /** SameAs URI JList. */
  public JList sameAsList = null;

  /** SameAs 'add' button. */
  public JButton sameAsButton = null;

  /** SameAs text field. */
  public JTextField sameAsText = null;

  /** SameAs list label. */
  private JLabel sameAsListLabel = null;

  /** SeeAlso list label. */
  private JLabel seeAlsoListLabel = null;

  /** Add sameAs button. */
  private JButton addSameAsButton = null;

  /** Remove sameAs button. */
  private JButton removeSameAsButton = null;

  /** Remove duplicates button. */
  private JButton removeDuplicatesButton = null;

  /** Remove tags button. */
  private JButton removeTagsButton = null;

  /** Add seeAlso button. */
  private JButton addSeeAlsoButton = null;

  /** Add seeAlso button. */
  private JButton addDuplicatesButton = null;

  /** Add seeAlso button. */
  private JButton addTagsButton = null;

  /** Remove seeAlso button. */
  private JButton removeSeeAlsoButton = null;

  /** Main container. */
  private Container container = null;

  /** SameAs List model. */
  private DefaultListModel sameAsListModel = null;

  /** SeeAlso List model. */
  private DefaultListModel seeAlsoListModel = null;

  /** Duplicates List model. */
  private DefaultListModel duplicatesListModel = null;

  /** Tags List model. */
  private DefaultListModel tagsListModel = null;

  public IssueSearchWizard(LinkedServiceDataUI parent) {
    super("Hackystat - Search for issues");
    mainframe = parent;
    container = this.getContentPane();
    refresh(true);
    pack();
    setSize(mainframe.popUpWinDimension);
    setLocationRelativeTo(null);
    setBackground(Color.white);
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent we) {
        setVisible(false);
        dispose();
      }
    });
    setVisible(true);
  }

  public void refresh(boolean reset) {
    container.removeAll();
    JPanel panel = new JPanel();
    panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
    panel.setBackground(Color.WHITE);
    if (mainframe.isLogged()) {
      initLabelHeaders1();
      initJTextFields(reset);
      panel.add(fillInIssueProfileData1());
      panel.add(getActions());
    }
    panel.setPreferredSize(mainframe.popUpWinDimension);
    panel.setBackground(Color.white);
    JScrollPane listScrollPane = new JScrollPane(panel);
    listScrollPane.setPreferredSize(mainframe.popUpWinDimension);
    listScrollPane.setMaximumSize(mainframe.popUpWinDimension);
    listScrollPane.setMinimumSize(mainframe.popUpWinDimension);
    container.add(listScrollPane);
    container.validate();
  }

  private void initJTextFields(boolean reset) {
    String empty = "";
    if (statusText == null || reset) {
      statusText = new JTextField(10);
      statusText = mainframe.initTextField(statusText, empty, true);
    }
    if (idText == null || reset) {
      idText = new JTextField(10);
      idText = mainframe.initTextField(idText, empty, true);
    }
    if (assignedToText == null || reset) {
      assignedToText = new JTextField(10);
      assignedToText = mainframe.initTextField(assignedToText, "", true);
    }
    if (typeText == null || reset) {
      typeText = new JTextField(10);
      typeText = mainframe.initTextField(typeText, empty, true);
    }
    if (priorityText == null || reset) {
      priorityText = new JTextField(10);
      priorityText = mainframe.initTextField(priorityText, empty, true);
    }
    if (milestoneText == null || reset) {
      milestoneText = new JTextField(10);
      milestoneText = mainframe.initTextField(milestoneText, empty, true);
    }
    if (duplicatesText == null || reset) {
      duplicatesText = new JTextField(10);
      duplicatesText = mainframe.initTextField(duplicatesText, empty, true);
    }
    if (tagsText == null || reset) {
      tagsText = new JTextField(10);
      tagsText = mainframe.initTextField(tagsText, empty, true);
    }
    if (seeAlsoText == null || reset) {
      seeAlsoText = new JTextField(10);
      seeAlsoText = mainframe.initTextField(seeAlsoText, empty, true);
    }
    if (sameAsText == null || reset) {
      sameAsText = new JTextField(10);
      sameAsText = mainframe.initTextField(sameAsText, empty, true);
    }
    String tooltip = "Use the date format 'yyyy-M-d' please";
    if (creationDateText == null || reset) {
      creationDateText = new JFormattedTextField(new SimpleDateFormat("yyyy-M-d"));
      creationDateText = mainframe
          .initFormattedDateTextField(creationDateText, "", true, tooltip);
    }
    if (closureDateText == null || reset) {
      closureDateText = new JFormattedTextField(new SimpleDateFormat("yyyy-M-d"));
      closureDateText = mainframe.initFormattedDateTextField(closureDateText, "", true, tooltip);
    }
    if (modifiedDateText == null || reset) {
      modifiedDateText = new JFormattedTextField(new SimpleDateFormat("yyyy-M-d"));
      modifiedDateText = mainframe
          .initFormattedDateTextField(modifiedDateText, "", true, tooltip);
    }
    return;
  }

  private JPanel fillInIssueProfileData1() {
    JPanel horiz = new JPanel();
    horiz.setLayout(new BoxLayout(horiz, BoxLayout.X_AXIS));
    horiz.setBackground(Color.white);
    JPanel vertic = null;

    vertic = new JPanel();
    vertic.setLayout(new BoxLayout(vertic, BoxLayout.Y_AXIS));
    vertic.setBackground(Color.white);
    vertic.add(statusLabel);
    vertic.add(Box.createVerticalStrut(1));
    vertic.add(statusText);
    vertic.add(Box.createVerticalStrut(3));
    vertic.add(typeLabel);
    vertic.add(Box.createVerticalStrut(1));
    vertic.add(typeText);
    vertic.add(Box.createVerticalStrut(3));
    vertic.add(idLabel);
    vertic.add(Box.createVerticalStrut(1));
    vertic.add(idText);
    vertic.add(Box.createVerticalStrut(3));
    vertic.add(assignedToLabel);
    vertic.add(Box.createVerticalStrut(1));
    vertic.add(assignedToText);
    vertic.add(Box.createVerticalStrut(3));
    vertic.add(priorityLabel);
    vertic.add(Box.createVerticalStrut(1));
    vertic.add(priorityText);
    vertic.add(Box.createVerticalStrut(3));
    vertic.add(milestoneLabel);
    vertic.add(Box.createVerticalStrut(1));
    vertic.add(milestoneText);
    vertic.add(Box.createVerticalStrut(3));
    vertic.add(creationDateLabel);
    vertic.add(Box.createVerticalStrut(1));
    vertic.add(creationDateText);
    vertic.add(Box.createVerticalStrut(3));
    vertic.add(closureDateLabel);
    vertic.add(Box.createVerticalStrut(1));
    vertic.add(closureDateText);
    vertic.add(Box.createVerticalStrut(3));
    vertic.add(modificationDateLabel);
    vertic.add(Box.createVerticalStrut(1));
    vertic.add(modifiedDateText);
    horiz.add(vertic);
    horiz.add(Box.createHorizontalStrut(5));

    vertic = new JPanel();
    vertic.setLayout(new BoxLayout(vertic, BoxLayout.Y_AXIS));
    vertic.setBackground(Color.white);

    if (sameAsListModel == null) {
      sameAsListModel = new DefaultListModel();
    }
    sameAsList = new JList(sameAsListModel);
    sameAsList = mainframe.initJList(sameAsList);
    JScrollPane listScrollPane = new JScrollPane(sameAsList);
    listScrollPane = mainframe.initJListScrollPane(listScrollPane);
    addSameAsButton = new JButton("Add >>");
    addSameAsButton = mainframe.initButton(addSameAsButton, this, mainframe.buttonDimension,
        "Add the selected sameAs URI to the list on the right.");
    removeSameAsButton = new JButton("Remove <<");
    removeSameAsButton = mainframe.initButton(removeSameAsButton, this, mainframe.buttonDimension,
        "Remove the selected sameAs URI from the list on the right.");
    vertic.add(mainframe.addJListFillingComponent(sameAsLabel, sameAsText, addSameAsButton,
        removeSameAsButton, sameAsListLabel, listScrollPane, ""));
    vertic.add(Box.createVerticalStrut(3));

    if (seeAlsoListModel == null) {
      seeAlsoListModel = new DefaultListModel();
    }
    seeAlsoList = new JList(seeAlsoListModel);
    seeAlsoList = mainframe.initJList(seeAlsoList);
    listScrollPane = new JScrollPane(seeAlsoList);
    listScrollPane = mainframe.initJListScrollPane(listScrollPane);
    addSeeAlsoButton = new JButton("Add >>");
    addSeeAlsoButton = mainframe.initButton(addSeeAlsoButton, this, mainframe.buttonDimension,
        "Add the selected seeAlso URI to the list on the right.");
    removeSeeAlsoButton = new JButton("Remove <<");
    removeSeeAlsoButton = mainframe.initButton(removeSeeAlsoButton, this,
        mainframe.buttonDimension, "Remove the selected seeAlso URI from the list on the right.");
    vertic.add(mainframe.addJListFillingComponent(seeAlsoLabel, seeAlsoText, addSeeAlsoButton,
        removeSeeAlsoButton, seeAlsoListLabel, listScrollPane, ""));

    if (duplicatesListModel == null) {
      duplicatesListModel = new DefaultListModel();
    }
    duplicatesList = new JList(duplicatesListModel);
    duplicatesList = mainframe.initJList(duplicatesList);
    listScrollPane = new JScrollPane(duplicatesList);
    listScrollPane = mainframe.initJListScrollPane(listScrollPane);
    addDuplicatesButton = new JButton("Add >>");
    addDuplicatesButton = mainframe.initButton(addSeeAlsoButton, this, mainframe.buttonDimension,
        "Add the selected duplicate URI to the list on the right.");
    removeDuplicatesButton = new JButton("Remove <<");
    removeDuplicatesButton = mainframe.initButton(removeDuplicatesButton, this,
        mainframe.buttonDimension, "Remove the selected duplicate URI from the list on the right.");
    vertic.add(mainframe.addJListFillingComponent(duplicatesLabel, duplicatesText,
        addDuplicatesButton, removeDuplicatesButton, duplicatesListLabel, listScrollPane, null));

    if (tagsListModel == null) {
      tagsListModel = new DefaultListModel();
    }
    tagsList = new JList(tagsListModel);
    tagsList = mainframe.initJList(tagsList);
    listScrollPane = new JScrollPane(tagsList);
    listScrollPane = mainframe.initJListScrollPane(listScrollPane);
    addTagsButton = new JButton("Add >>");
    addTagsButton = mainframe.initButton(addTagsButton, this, mainframe.buttonDimension,
        "Add the selected tag to the list on the right.");
    removeTagsButton = new JButton("Remove <<");
    removeTagsButton = mainframe.initButton(removeTagsButton, this, mainframe.buttonDimension,
        "Remove the selected tag from the list on the right.");
    vertic.add(mainframe.addJListFillingComponent(tagsLabel, tagsText, addTagsButton,
        removeTagsButton, tagsListLabel, listScrollPane, null));

    horiz.add(vertic);
    return horiz;
  }

  private JPanel getActions() {
    JPanel panel = new JPanel();
    panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
    panel.setBackground(Color.white);
    searchButton = new JButton("Search");
    searchButton = mainframe.initButton(searchButton, this, mainframe.buttonDimension,
        "Start search");
    panel.add(searchButton);
    panel.add(Box.createHorizontalStrut(5));
    cancelButton = new JButton("Cancel");
    cancelButton = mainframe.initButton(cancelButton, this, mainframe.buttonDimension,
        "Reset fields.");
    panel.add(cancelButton);
    return panel;
  }

  private void initLabelHeaders1() {
    if (duplicatesLabel == null) {
      duplicatesLabel = new JLabel();
      duplicatesLabel = mainframe.initLabel(duplicatesLabel, "URI:");
    }

    if (idLabel == null) {
      idLabel = new JLabel();
      idLabel = mainframe.initLabel(idLabel, "ID:");
    }

    if (statusLabel == null) {
      statusLabel = new JLabel();
      statusLabel = mainframe.initLabel(statusLabel, "Status:");
    }

    if (typeLabel == null) {
      typeLabel = new JLabel();
      typeLabel = mainframe.initLabel(typeLabel, "Type:");
    }

    if (priorityLabel == null) {
      priorityLabel = new JLabel();
      priorityLabel = mainframe.initLabel(priorityLabel, "Priority:");
    }

    if (milestoneLabel == null) {
      milestoneLabel = new JLabel();
      milestoneLabel = mainframe.initLabel(milestoneLabel, "Milestone:");
    }

    if (assignedToLabel == null) {
      assignedToLabel = new JLabel();
      assignedToLabel = mainframe.initLabel(assignedToLabel, "Assigned to:");
    }

    if (tagsLabel == null) {
      tagsLabel = new JLabel();
      tagsLabel = mainframe.initLabel(tagsLabel, "Tag:");
    }

    if (creationDateLabel == null) {
      creationDateLabel = new JLabel();
      creationDateLabel = mainframe.initLabel(creationDateLabel, "Created:");
    }

    if (closureDateLabel == null) {
      closureDateLabel = new JLabel();
      closureDateLabel = mainframe.initLabel(closureDateLabel, "Closed:");
    }

    if (modificationDateLabel == null) {
      modificationDateLabel = new JLabel();
      modificationDateLabel = mainframe.initLabel(modificationDateLabel, "Modified:");
    }

    if (sameAsLabel == null) {
      sameAsLabel = new JLabel();
      sameAsLabel = mainframe.initLabel(sameAsLabel, "SameAs URI:");
    }

    if (seeAlsoLabel == null) {
      seeAlsoLabel = new JLabel();
      seeAlsoLabel = mainframe.initLabel(seeAlsoLabel, "SeeAlso URI:");
    }

    if (duplicatesListLabel == null) {
      duplicatesListLabel = new JLabel();
      duplicatesListLabel = mainframe
          .initLabel(duplicatesListLabel, "List of selected duplicates:");
    }

    if (tagsListLabel == null) {
      tagsListLabel = new JLabel();
      tagsListLabel = mainframe.initLabel(tagsListLabel, "List of selected tags:");
    }

    if (sameAsListLabel == null) {
      sameAsListLabel = new JLabel();
      sameAsListLabel = mainframe.initLabel(sameAsListLabel, "List of selected sameAs URI:");
    }

    if (seeAlsoListLabel == null) {
      seeAlsoListLabel = new JLabel();
      seeAlsoListLabel = mainframe.initLabel(seeAlsoListLabel, "List of selected seeAlso URI:");
    }
  }

  @Override
  public void itemStateChanged(ItemEvent e) {

  }

  @Override
  public void actionPerformed(ActionEvent e) {
    Object obj = e.getSource();
    String text = null;
    if (obj.equals(addSeeAlsoButton)) {
      text = seeAlsoText.getText();
      if (!text.startsWith("http://")) {
        JOptionPane.showMessageDialog(this, "The inserted URI must begin with 'http://'",
            "Hackystat - Error Message", JOptionPane.ERROR_MESSAGE);
        return;
      }
      seeAlsoListModel.add(seeAlsoListModel.getSize(), text);
      seeAlsoList.repaint();
    }
    else if (obj.equals(addSameAsButton)) {
      text = sameAsText.getText();
      if (!text.startsWith("http://")) {
        JOptionPane.showMessageDialog(this, "The inserted URI must begin with 'http://'",
            "Hackystat - Error Message", JOptionPane.ERROR_MESSAGE);
        return;
      }
      sameAsListModel.add(sameAsListModel.getSize(), text);
      sameAsList.repaint();
    }
    else if (obj.equals(addDuplicatesButton)) {
      text = duplicatesText.getText();
      if (!text.startsWith("http://")) {
        JOptionPane.showMessageDialog(this, "The inserted URI must begin with 'http://'",
            "Hackystat - Error Message", JOptionPane.ERROR_MESSAGE);
        return;
      }
      duplicatesListModel.add(duplicatesListModel.getSize(), text);
      duplicatesList.repaint();
    }
    else if (obj.equals(addTagsButton)) {
      text = tagsText.getText();
      tagsListModel.add(tagsListModel.getSize(), text);
      tagsList.repaint();
    }
    else if (obj.equals(removeSeeAlsoButton)) {
      if (!seeAlsoList.isSelectionEmpty()) {
        int index = seeAlsoList.getSelectedIndex();
        if (index != -1) {
          seeAlsoListModel.remove(index);
          seeAlsoList.repaint();
        }
      }
      refresh(false);
    }
    else if (obj.equals(removeSameAsButton)) {
      if (!sameAsList.isSelectionEmpty()) {
        int index = sameAsList.getSelectedIndex();
        if (index != -1) {
          sameAsListModel.remove(index);
          sameAsList.repaint();
        }
      }
      refresh(false);
    }
    else if (obj.equals(removeDuplicatesButton)) {
      if (!duplicatesList.isSelectionEmpty()) {
        int index = duplicatesList.getSelectedIndex();
        if (index != -1) {
          duplicatesListModel.remove(index);
          duplicatesList.repaint();
        }
      }
      refresh(false);
    }
    else if (obj.equals(removeTagsButton)) {
      if (!tagsList.isSelectionEmpty()) {
        int index = tagsList.getSelectedIndex();
        if (index != -1) {
          tagsListModel.remove(index);
          tagsList.repaint();
        }
      }
      refresh(false);
    }
    else if (obj.equals(cancelButton)) {
      refresh(true);
    }
    else if (obj.equals(searchButton)) {
      IssueQuery iq = new IssueQuery();
      String str = milestoneText.getText(), empty = "";
      if (str != null && !str.trim().equals(empty)) {
        iq.milestone = str;
      }
      str = creationDateText.getText();
      if (str != null && !str.trim().equals(empty)) {
        iq.created = str;
      }
      str = closureDateText.getText();
      if (str != null && !str.trim().equals(empty)) {
        iq.closed = str;
      }
      str = modifiedDateText.getText();
      if (str != null && !str.trim().equals(empty)) {
        iq.lastmod = str;
      }
      str = priorityText.getText();
      if (str != null && !str.trim().equals(empty)) {
        iq.priority = str;
      }
      str = statusText.getText();
      if (str != null && !str.trim().equals(empty)) {
        iq.status = str;
      }
      str = idText.getText();
      if (str != null && !str.trim().equals(empty)) {
        iq.id = str;
      }
      str = typeText.getText();
      if (str != null && !str.trim().equals(empty)) {
        iq.type = str;
      }
      str = assignedToText.getText();
      if (str != null && !str.trim().equals(empty)) {
        iq.assignedTo = str;
      }
      String[] risp = mainframe.getJListContent(sameAsListModel);
      if (risp.length != 0) {
        iq.sameAs = risp;
      }
      risp = mainframe.getJListContent(seeAlsoListModel);
      if (risp.length != 0) {
        iq.seeAlso = risp;
      }
      risp = mainframe.getJListContent(duplicatesListModel);
      if (risp.length != 0) {
        iq.duplicates = risp;
      }
      risp = mainframe.getJListContent(tagsListModel);
      if (risp.length != 0) {
        iq.tags = risp;
      }
      try {
        String queryResult = mainframe.getLiSeDClient().searchForIssues(iq);
        queryResult = mainframe.getURIList(queryResult);
        mainframe.displayQueryResults(queryResult);
      }
      catch (Exception e1) {
        JOptionPane.showMessageDialog(this, e1.getMessage(), "Hackystat - Error Message",
            JOptionPane.ERROR_MESSAGE);
        e1.printStackTrace();
        return;
      }
    }
  }
}
